package com.sky.service.impl;

import cn.mybatis.mp.core.mybatis.mapper.context.Pager;
import cn.mybatis.mp.core.sql.executor.chain.QueryChain;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.GetBorroweuestsDTO;
import com.sky.entity.Books;
import com.sky.entity.Borrowrequests;
import com.sky.entity.Users;
import com.sky.exception.BaseException;
import com.sky.mapper.BooksMapper;
import com.sky.mapper.BorrowrequestsMapper;
import com.sky.mapper.UsersMapper;
import com.sky.service.UserBorrowService;
import com.sky.utils.SnowflakeIdWorkerUtil;
import com.sky.vo.GetBorroweuestsVO;
import com.sky.webSocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Map;
import java.util.HashMap;

/**
 * 用户借阅服务实现类
 */
@Service
@Slf4j
public class UserBorrowServiceImpl implements UserBorrowService {

    @Autowired
    private BooksMapper booksMapper;

    @Autowired
    private BorrowrequestsMapper borrowrequestsMapper;

    @Autowired
    private SnowflakeIdWorkerUtil snowflakeIdWorkerUtil;

    @Autowired
    private WebSocketServer webSocketServer;

    @Autowired
    private UsersMapper usersMapper;

    /**
     * 提交借阅申请
     *
     * @param userId 用户ID
     * @param bookId 图书ID
     */
    @Override
    @Transactional
    public void submitBorrowRequest(Integer userId, Integer bookId) {
        log.info("开始处理借阅申请 - userId: {}, bookId: {}", userId, bookId);

        // 1. 检查用户是否存在
        Users user = usersMapper.get(where -> where.eq(Users::getUserId, userId));
        if (user == null) {
            log.error("用户不存在 - userId: {}", userId);
            throw new BaseException(MessageConstant.USER_NOT_FOUND);
        }
        log.info("用户验证通过 - userName: {}", user.getUsername());

        // 2. 检查图书是否存在
        Books book = booksMapper.get(where -> where.eq(Books::getBookId, bookId));
        if (book == null) {
            log.error("图书不存在 - bookId: {}", bookId);
            throw new BaseException(MessageConstant.BOOK_NOT_FOUND);
        }
        log.info("图书验证通过 - bookTitle: {}", book.getTitle());

        // 3. 检查图书库存
        if (book.getStockQuantity() <= 0) {
            throw new BaseException(MessageConstant.LACK_OF_BOOKS_IN_STOCK);
        }

        // 4. 检查是否有未完成的借阅申请
        Borrowrequests existingRequest = QueryChain.of(borrowrequestsMapper)
                .eq(Borrowrequests::getUserId, userId)
                .eq(Borrowrequests::getBookId, bookId)
                .in(Borrowrequests::getStatus, StatusConstant.PENDING, StatusConstant.APPROVED)
                .get();

        if (existingRequest != null) {
            throw new BaseException(MessageConstant.DUPLICATE_BORROW_REQUEST);
        }

        // 5. 创建借阅申请
        Borrowrequests request = new Borrowrequests();
        request.setUserId(userId);
        request.setBookId(bookId);
        request.setRequestDate(new Date());
        request.setStatus(StatusConstant.PENDING);
        
        borrowrequestsMapper.save(request);
        
        // 6. 发送WebSocket通知
        Map<String, Object> message = new HashMap<>();
        message.put("type", "BORROW_REQUEST");
        message.put("action", "refresh");
        message.put("message", "新的借阅申请已提交");
        message.put("data", new HashMap<String, Object>() {{
            put("requestId", request.getRequestId());
            put("bookId", bookId);
            put("status", StatusConstant.PENDING);
            put("bookTitle", book.getTitle());
            put("userName", userId);
            put("requestTime", new Date());
        }});
        
        // 通知所有在线管理员刷新借阅申请列表
        webSocketServer.sendToAllAdmins(message);
        
        log.info("用户 {} 提交借阅申请 - 图书: {}, 申请ID: {}", 
                userId, bookId, request.getRequestId());
    }

    /**
     * 取消借阅申请
     *
     * @param userId 用户ID
     * @param requestId 申请ID
     */
    @Override
    @Transactional
    public void cancelBorrowRequest(Integer userId, String requestId) {
        // 1. 查询借阅申请
        Borrowrequests request = borrowrequestsMapper.get(where -> 
            where.eq(Borrowrequests::getRequestId, requestId)
        );

        if (request == null) {
            throw new BaseException(MessageConstant.REQUEST_NOT_FOUND);
        }

        // 2. 验证用户身份
        if (!request.getUserId().equals(userId)) {
            throw new BaseException(MessageConstant.UNAUTHORIZED_OPERATION);
        }

        // 3. 检查申请状态
        if (!StatusConstant.PENDING.equals(request.getStatus())) {
            throw new BaseException(MessageConstant.INVALID_REQUEST_STATUS);
        }

        // 4. 更新申请状态为已取消
        request.setStatus(StatusConstant.CANCELLED);
        request.setReviewDate(new Date());
        borrowrequestsMapper.update(request);

        // 5. 获取图书信息用于通知
        Books book = booksMapper.get(where -> where.eq(Books::getBookId, request.getBookId()));
        
        // 6. 发送WebSocket通知
        Map<String, Object> message = new HashMap<>();
        message.put("type", "BORROW_REQUEST");
        message.put("action", "refresh");
        message.put("message", "借阅申请已取消");
        message.put("data", new HashMap<String, Object>() {{
            put("requestId", requestId);
            put("bookId", request.getBookId());
            put("status", StatusConstant.CANCELLED);
            put("bookTitle", book != null ? book.getTitle() : "未知图书");
            put("userName", userId);
            put("cancelTime", new Date());
        }});
        
        // 通知所有在线管理员刷新借阅申请列表
        webSocketServer.sendToAllAdmins(message);
        
        log.info("用户 {} 取消借阅申请 - 申请ID: {}", userId, requestId);
    }
} 